//
//  GetOptions.m
//  GetoptCocoa
//
//  Created by Andrew Pressel on 7/6/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "GetOptions.h"


@implementation GetOptions

-(id) init:(NSArray*)parms{
	return [self init:parms withDefaults:nil];
}

-(id) init:(NSArray*)parms withDefaults:(NSDictionary *)defaults{
	encoding = [NSString defaultCStringEncoding];
	options = [NSMutableDictionary dictionaryWithDictionary:defaults];
	
	NSArray *args = [[NSProcessInfo processInfo] arguments];
	//NSLog(@"Arguments:%@\n", args);
	
	int errors = 0;
	for(int i=1; i<[args count]; i++){
		NSMutableString* str = 
		[NSMutableString stringWithString:[args objectAtIndex:i]];
		NSArray* pair = nil;
		
		int pCount = 0;
		while( [str characterAtIndex:0] == '-' ){
			[str deleteCharactersInRange:NSMakeRange(0,1)];
			pCount++;
		}
		
		switch(pCount){
			case 2:
				pair = [str componentsSeparatedByString:@"="];
				errors += [self checkParameter:pair against:parms];
				break;
			case 1:{
				NSString* str2 = [args objectAtIndex:i+1];
				if( [str2 hasPrefix:@"-"] ){
					pair = [NSArray arrayWithObjects:str, nil];
				}else{
					pair = [NSArray arrayWithObjects:str, str2, nil];
					i++;
				}
				errors += [self checkParameter:pair against:parms];
				break;
			}
			default:
				printf("Invalid argument[%s][%d]\n", [str cStringUsingEncoding:encoding], pCount);
				exit(99);
		}
	}
	
	if( errors ){
		return nil;
	}
	return self;
}

-(int) checkParameter:(NSArray *)pair against:(NSArray*)parameters{
	int found = 0;
	int error = 0;
	
	//NSLog(@"****\n[%@]\n", pair);
	NSMutableString* key = [NSMutableString stringWithCapacity:0];
	for(id parm in parameters){
		//NSLog(@"  [%@]\n", parm);
		if( [parm hasPrefix:[pair objectAtIndex:0]] ){
			if(found > 0 ){
				[key appendString:@", "];
			}
			found++;
			[key appendString:parm];
		}
	}
	
	if( found == 0 ){
		printf("Unknown option: \"%s\"\n", [[pair objectAtIndex:0] cStringUsingEncoding:encoding]);
		return 1;
	}
	
	if( found > 1 ){
		printf("%s is ambiguous (%s)\n",
			   [[pair objectAtIndex:0] cStringUsingEncoding:encoding],
			   [key cStringUsingEncoding:encoding]);
		return 1;
	}
	
	NSArray* param = [key componentsSeparatedByString:@"="];
	//NSLog(@"param:%@\n", param);
	if( [param count] > 1){
		NSScanner* scanner = [NSScanner scannerWithString:[pair objectAtIndex:1]];
		if( [[param objectAtIndex:1] isEqualTo:@"i"] ){
			double number;
			if( [scanner scanDouble:&number] ){
				[options setObject:[NSNumber numberWithDouble:number] forKey:[param objectAtIndex:0]];
			}else{
				printf("Value \"%s\" invalid for option %s: number expected\n",
					   [[param objectAtIndex:0] cStringUsingEncoding:encoding],
					   [[param objectAtIndex:1] cStringUsingEncoding:encoding]
					   );
				error++;
			}
		}
		if( [[param objectAtIndex:1] isEqualTo:@"s"] ){
			printf("setting: %s => %s\n", 
				   [[param objectAtIndex:0] cStringUsingEncoding:encoding],
				   [[param objectAtIndex:1] cStringUsingEncoding:encoding]);
			[options setObject:[pair objectAtIndex:1] forKey:[param objectAtIndex:0]];
		}
	}else {
		[options setObject:[NSNumber numberWithBool:YES] forKey:key];
	}
	
	
	//NSLog(@"Found: [%d] matches [%@]\n", found, key);
	return error;
}


-(int) count{ 
	return [options count];
}


-(id) optionNamed:(NSString *)optname{
	return [options objectForKey:optname];
}

-(NSString*) description{
	NSMutableString* desc = [NSMutableString string];
	[desc appendString:@"GetOptions{\n"];
	
	for(id key in options){
		[desc appendFormat:@"  %@ => %@,\n", key, [options objectForKey:key]];
	}
	
	[desc appendString:@"}"];
	return desc;
}

@end
